package com.concurrent.sample.common.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class InstantUtils {
    public static final ZoneId DEFAULT_TIMEZONE = ZoneId.systemDefault();

    /**
     * 将字符串（格式 yyyy-MM-dd HH:mm:ss）转为 Instant
     */
    public static Instant toInstant(String str) {
        return StrUtil.isBlank(str) ? null : LocalDateTime.parse(str, DatePattern.NORM_DATETIME_FORMATTER).atZone(DEFAULT_TIMEZONE).toInstant();
    }

    /**
     * 将 Instant 转为字符串（格式 yyyy-MM-dd HH:mm:ss）
     */
    public static String format(Instant instant) {
        return instant == null ? null : DatePattern.NORM_DATETIME_FORMATTER.format(instant);
    }

    /**
     * 将 Instant 转为字符串（格式 yyyy-MM-dd）
     */
    public static String format2Date(Instant instant) {
        return instant == null ? null : toLocalDate(instant).toString();
    }

    /**
     * 将 Instant 转为 LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(Instant instant) {
        return instant == null ? null : LocalDateTime.ofInstant(instant, DEFAULT_TIMEZONE);
    }

    /**
     * 将 LocalDateTime 转为 Instant
     */
    public static Instant toInstant(LocalDateTime localDateTime) {
        return localDateTime == null ? null : localDateTime.atZone(DEFAULT_TIMEZONE).toInstant();
    }

    /**
     * 将 Instant 转为 LocalDate
     */
    public static LocalDate toLocalDate(Instant instant) {
        return instant == null ? null : LocalDateTime.ofInstant(instant, DEFAULT_TIMEZONE).toLocalDate();
    }

    /**
     * 将 LocalDate 转为当天开始的 Instant
     */
    public static Instant toInstant(LocalDate localDate) {
        return localDate == null ? null : localDate.atStartOfDay(DEFAULT_TIMEZONE).toInstant();
    }

    /**
     * 将 LocalDate 转为当天结束的 Instant
     */
    public static Instant toEndDateInstant(LocalDate endDate) {
        return endDate == null ? null : endDate.atStartOfDay(DEFAULT_TIMEZONE).plusDays(1).minusNanos(1).toInstant();
    }
}
